<template>
  <!--#region 字段选择弹出层-->
  <el-popover
    ref="fieldPickerRef"
    :virtual-ref="dynamicRef"
    :visible="fieldPickerVisible"
    :show-arrow="false"
    width="280px"
    @hide="onHide"
  >
    <div id="field-picker">
      <el-scrollbar :max-height="320" view-class="pr-4">
        <ul>
          <li
            v-for="col in selectableColumns"
            :key="col.field"
            class="flex items-center gap-x-2 py-2 px-4 rounded-md hover:bg-gray-200 text-lg"
            @click="onPickColumn(col)"
          >
            <div class="shrink-0">
              <i :class="['text-[18px]', typeIcon[col.type]]" />
            </div>
            <span
              class="inline-block grow leading-none truncate select-none"
            >
							{{ col.title }}
						</span>
          </li>
        </ul>
      </el-scrollbar>
    </div>
  </el-popover>
  <!--#endregion-->
</template>
<script setup lang="ts">
import { typeIcon, promiseResolver, type PromiseResolver } from '../lib'
import type { ColumnConfig } from '../types'
import { type Ref, ref } from 'vue'
import { useToggle } from "@vueuse/core";

const emit = defineEmits<{
  pick: [ col: ColumnConfig ]
}>()
const dynamicRef: Ref<HTMLElement | null> = ref(null)
// 字段选择器
const fieldPickerRef = ref()
const setVirtualRef = (virtualRef: HTMLElement | null): void => {
  dynamicRef.value = virtualRef
}
// 字段选择器可见状态
const [ fieldPickerVisible, toggleFieldPickerVisible ] = useToggle(false)

const selectableColumns: Ref<ColumnConfig[]> = ref([])
const setSelectableColumns = (cols: ColumnConfig[]) => {
  selectableColumns.value = cols
}

let resolver: PromiseResolver<ColumnConfig>
const pick = () => {
  resolver = promiseResolver<ColumnConfig>()
  return resolver.promise
}

const onPickColumn = (col: ColumnConfig) => {
  resolver && resolver.resolve(col)
  emit('pick', col)
}
const onHide = () => {
  resolver && resolver.reject(true)
  setVirtualRef(null)
}
defineExpose({
  setVirtualRef,
  toggleVisible: toggleFieldPickerVisible,
  pick,
  setSelectableColumns
})
</script>
